//
// Created by ta&to on 2022/10/28.
//

#include "http_net_config.h"
#define NUMBER16 "[0-9a-fA-F]"
void init_rep(struct responseContext* response) {
    response->fd = -1;
    response->fd_errno = -1;
    response->client_fd = -1;
    response->client_fd_errno = -1;
    response->head = NULL;
    response->prev_buf = NULL;
    response->buf = NULL;
    response->buf_len = 0;
    response->attr = NULL;
    response->hset = NULL;
    response->rep_stream.read_end = 0;
    response->rep_stream.reading = 0;
    response->rep_stream.need_read_len = 0;
    response->rep_stream.has_readed = 0;
    response->rep_stream.remaining_read = 0;
}
static inline int __next_body_str_len(dts buf) {
    int len = -1;
    dts buf_ = dtsnew(buf);
    regmatch_t nmatch[1];
    if(regex(buf, "("CRLF CRLF NUMBER16"+"CRLF")", nmatch, sizeof(nmatch) / sizeof(regmatch_t)) == 0) {
        for(int i = 0;i < (sizeof(nmatch)/sizeof(regmatch_t));i++){
            int start = nmatch[i].rm_so;
            int end = nmatch[i].rm_eo;
            if(start > -1 && end > -1) {
                dtsrange(buf_, start, end-1);
                if(regex(buf_, "("NUMBER16"+)", nmatch, sizeof(nmatch) / sizeof(regmatch_t)) == 0) {
                    start = nmatch[i].rm_so;
                    end = nmatch[i].rm_eo;
                    if(start > -1 && end > -1) {
                        dtsrange(buf_, start, end-1);
                        len = buf_ ? htoi(buf_):len;
                    }
                }
            }
        }
    }
    dtsfree(buf_);
    return len;
}
static inline void __stream_body_do(struct responseContext *rpctx){
    u_char* tail_pos = (u_char *) CRLF "0" CRLF CRLF;
    if(rpctx->attr->Content_Length == -1 && !rpctx->attr->Transfer_Encoding) {
        rpctx->rep_stream.read_end = 1;
        rpctx->rep_stream.reading = 0;
    }
    if(rpctx->prev_buf){
        dts stream_ = dtsnew(rpctx->prev_buf);
        stream_ = dtscat(stream_, rpctx->buf);
        if(rpctx->attr->Content_Length != -1) {
            rpctx->rep_stream.need_read_len = rpctx->attr->Content_Length;
            rpctx->rep_stream.has_readed += rpctx->buf_len;
            rpctx->rep_stream.need_read_len = rpctx->rep_stream.need_read_len - rpctx->rep_stream.has_readed;
            rpctx->rep_stream.read_end = (rpctx->rep_stream.need_read_len == 0) ? 1 : 0;
            rpctx->rep_stream.reading = (rpctx->rep_stream.need_read_len > 0) ? 0 : 1;
        } else if(!dtscasecmpstr(rpctx->attr->Transfer_Encoding, "chunked")) {
            rpctx->rep_stream.need_read_len = __next_body_str_len(stream_);
            int end = indexnof(stream_, dtslen(stream_), tail_pos, strlen(tail_pos));
            rpctx->rep_stream.read_end = (end > -1) ? 1 : 0;
            rpctx->rep_stream.reading = (end > -1) ? 0 : 1;
        }
        dtsfree(stream_);
    }
}
// 返回头处理程序
void response_control(http_inner_response_before_facade_t *hirpbef) {
}

void _file_before_response_callback(struct responseContext *rpctx) {
    debug(rpctx->hset->logs, "_file_before_response_callback");
}
void _file_running_response_callback(struct responseContext *rpctx) {
    debug(rpctx->hset->logs, "_file_running_response_callback");
}
void _file_after_response_callback(struct responseContext *rpctx) {
    debug(rpctx->hset->logs, "_file_after_response_callback");
}

void _port_before_response_callback(struct responseContext *rpctx) {
    _port_rep_analysis_head(rpctx);
}
void _port_running_response_callback(struct responseContext *rpctx) {
    __stream_body_do(rpctx);
}
void _port_after_response_callback(struct responseContext *rpctx) {
    _clear_rep_head(rpctx);
}
